/**********************************************************************************
// DemoGeometry
//
// Creation:	12 Oct 2007
// Updated:		27 May 2011
// Compiler:	Visual Studio 2010
//
// Notes:		Colision detection among different geometries.
//
**********************************************************************************/

#define WIN32_LEAN_AND_MEAN  // just say no to MFC

#include "Resources.h"
#include "Anabele.h"	


/**********************************************************************************/
/*                          GeometryDemo Class                                    */
/**********************************************************************************/

class GeometryDemo: public D3DGame
{
private:
	Sprite * demobox;
	Sprite * demobar;
	SceneManager sm;

	Rect   rect1;
	Rect   rect2;
	Circle circ1;
	Poly   poly1;
	Poly   plane;
	Point  point;

	Color dColor;

	float dirX, dirY;

	char text[120];
	bool viewBR;

public:
	GeometryDemo();
	void InitObjects();

	void GameInit();
	void GameLogic();
	void GameDraw();
	void GameShutDown();
	void UnloadResources();
	void LoadResources();
};

/**********************************************************************************/

GeometryDemo::GeometryDemo()
{
	viewBR = false;
	dirX = 4;
	dirY = -2;
}

/**********************************************************************************/
void GeometryDemo::InitObjects()
{
	Point vlist[24] = { Point(1,11),
						Point(2,8),
						Point(1,7),
						Point(1,-1),
						Point(3,-1),
						Point(3,-2),
						Point(11,-3),
						Point(11,-6),
						Point(3,-7),
						Point(2,-8),
						Point(1,-8),
						Point(1,-7),
						Point(-1,-7),
						Point(-1,-8),
						Point(-2,-8),
						Point(-3,-7),
						Point(-11,-6),
						Point(-11,-3),
						Point(-3,-2),
						Point(-3,-1),
						Point(-1,-1),
						Point(-1,7),
						Point(-2,8),
						Point(-1, 11)};

	Point vlist2[8] = {	Point(151,-154), 
						Point(179,110), 
						Point(-54,208), 
						Point(-119,94), 
						Point(-187,116), 
						Point(-225,24), 
						Point(-63,-202), 
						Point(59,-118)};

	
	rect1 = Rect(-100, -100, 100, 100);
	rect2 = Rect(-200, -200, 200, 200);
	circ1 = Circle(150.0f);
	poly1 = Poly(vlist2, 8);

	plane = Poly(vlist, 24);
	point = Point(350.0f, 750.0f);

	rect1.MoveTo(450.0f, 250.0f);
	rect2.MoveTo(1000.0f, 750.0f);
	circ1.MoveTo(500.0f, 640.0f);
	poly1.MoveTo(950.0f, 280.0f);
	plane.MoveTo(200.0f, 500.0f);

	plane.Scale(8.0f, 8.0f);

	dColor = Color(255,255,255);
}

/**********************************************************************************/

void GeometryDemo::GameInit()
{
	srand(GetTickCount());
	
	InitObjects();

	sm.RegisterStatic(rect1);
	sm.RegisterStatic(rect2);
	sm.RegisterStatic(circ1);
	sm.RegisterStatic(poly1);
	sm.RegisterMoving(plane);
	sm.RegisterMoving(point);

	LoadResources();
}

/**********************************************************************************/

void GeometryDemo::LoadResources()
{
	demobox = new Sprite("Resources/demoBox.png");
	demobox->MoveTo(155, 100);
	
	demobar = new Sprite("Resources/demoBar.png");
	demobar->MoveTo(GetWindowWidth()/2.0f, GetWindowHeight()-30.0f);
}

/**********************************************************************************/

void GeometryDemo::UnloadResources()
{
	if (demobar) delete demobar;
	if (demobox) delete demobox;
}

/**********************************************************************************/

void GeometryDemo::GameShutDown()
{
	UnloadResources();
}

/**********************************************************************************/

void GeometryDemo::GameLogic()
{

	// Quits by pressing ESC
	EndsOnEscape();

	// Restart Game
	if (KeyDown('R'))
		InitObjects();

	// Enable Bounding Rectangle
	if (KeyDown('E'))
		viewBR = true;

	// Disable Bounding Rectangle
	if (KeyDown('D'))
		viewBR = false;

	// Scale
	if (KeyDown('A')) // scale up
		plane.Scale(1.1f, 1.1f);
	else
	if (KeyDown('S')) // scale down
		plane.Scale(0.9f, 0.9f);

	// Rotate
	if (KeyDown('Z')) // rotate left
		plane.Rotate(-5);
	else
	if (KeyDown('X')) // rotate right
		plane.Rotate(5);

	// Translate
	if (KeyDown(VK_RIGHT)) // translate right
		plane.Translate(5,0);
	else
	if (KeyDown(VK_LEFT))  // translate left
		plane.Translate(-5,0);    

	if (KeyDown(VK_UP))    // translate up
		plane.Translate(0,-5); 
	else
	if (KeyDown(VK_DOWN))  // translate down
		plane.Translate(0,5);

	poly1.Rotate(-1);
	plane.Rotate(3);

	// Point animation
	point.Translate(dirX,dirY);

	if (point.IntX() >= GetWindowWidth()-1)
		dirX = -dirX;

	if (point.IntX() <= 0)
		dirX = -dirX;

	if (point.IntY() >= GetWindowHeight()-1)
		dirY = -dirY;

	if (point.IntY() <= 0)
		dirY = -dirY;

	rect1.color = dColor;
	rect2.color = dColor;
	circ1.color = dColor;
	poly1.color = dColor;
	plane.color = dColor;
	point.color = dColor;

	// Test for collision
	if (sm.CollisionDetection())
	{
		pair<GameObject*,GameObject*> pairObjs;

		while ((pairObjs = sm.OnCollisionObjects()) != pair<GameObject*,GameObject*>(nullptr,nullptr))
		{

			((Geometry*) pairObjs.first)->color = Color(65,250,0);
			((Geometry*) pairObjs.second)->color = Color(65,250,0);
		}
	}
} 

/**********************************************************************************/

void GeometryDemo::GameDraw()
{
	// Lock screen for pixel plotting functions
	LockScreen();

	// Draw polygons
	rect1.Draw();
	rect2.Draw();
	circ1.Draw();
	poly1.Draw();
	plane.Draw();
	point.Draw();
				
	// Draw the bounding boxes
	if (viewBR)
	{
		poly1.GetBBox().color = Color(255,40,70);
		plane.GetBBox().color = Color(255,40,70);
		poly1.GetBBox().Draw();
		plane.GetBBox().Draw();
		
	}

	UnLockScreen();

	demobox->Draw();
	demobar->Draw();

	sprintf_s(text, "Geometry Demo");
	sysFont->Draw(55, 40, text);

	sprintf_s(text, "Colision with Multiple Geometries");
	sysFont->Draw(55, 80, text);

	sprintf_s(text, "<E> - Enable the bounding boxes");
	sysFont->Draw(55, 100, text);

	sprintf_s(text, "<D> - Disable the bounding boxes");
	sysFont->Draw(55, 120, text);

	sprintf_s(text, "<R> - Restart");
	sysFont->Draw(55, 140, text);

	sprintf_s(text, "<A> and <S> Scale    <Z> and <X> - Rotate    <Arrows> - Translate");
	sysFont->Draw(0, GetWindowHeight()-37, text, Color(255,255,255), GetWindowWidth(), 30, DT_CENTER);
} 


/**********************************************************************************/
/*                                  WinMain                                       */
/**********************************************************************************/

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	GeometryDemo bsdemo;

	//bsdemo.SetWindowMode(WINDOWED);
	//bsdemo.SetWindowSize(1024,768);		
	bsdemo.SetWindowBgColor(10,25,55);
	bsdemo.SetWindowTitle(string("Geometry Demo"));
	bsdemo.SetWindowIcon(LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON)));
	bsdemo.ShowWindowCursor(false);
	bsdemo.Initialize(hInstance);
	bsdemo.Start();
	
	return 0;

}

/**********************************************************************************/